<template>
    <div class="hello">
        <Alert>
            <Button type="primary" @click="buildDom">运行</Button>
            <Button type="primary" @click="beautifyAction">代码格式化</Button>
            <Button type="dashed" class="mt10">获取代码</Button>
        </Alert>
    </div>
</template>

<script>
import Vue from 'vue'
import Beautify from 'js-beautify'

export default {
  name: 'VueCodeRun',
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      code: this.value,
      html: '',
      js: '',
      css: '',
      program: null
    }
  },
  watch: {
    value (val) {
      this.code = val
    }
  },
  methods: {
    getSource (source, type) {
      const regex = new RegExp(`<${type}[^>]*>`)
      let openingTag = source.match(regex)
      if (!openingTag) return ''
      else openingTag = openingTag[0]

      return source.slice(
        source.indexOf(openingTag) + openingTag.length,
        source.lastIndexOf(`</${type}>`)
      )
    },
    splitCode () {
      const script = this.getSource(this.code, 'script').replace(
        /export default/,
        'return '
      )
      const style = this.getSource(this.code, 'style')
      const template = '<div id="code-running">' + this.getSource(this.code, 'template') + '</div>'
      this.js = script
      this.css = style
      this.html = template
    },
    buildDom () {
      this.reset()
      this.splitCode()
      if (this.html === '' || this.js === '') {
        this.$Message.warning(`请输入有效的Vue代码${Math.floor(Math.random() * 1000)}`)
        // eslint-disable-next-line semi
        return;
      }
      // eslint-disable-next-line no-new-func
      const common = new Function(this.js)()
      common.template = this.html
      const Template = Vue.extend(common)
      this.program = new Template()
      console.log(this.program.$mount().$el, '222222')
      let res = Vue.compile(this.html)
      console.log(res, '099999999')
      console.log(JSON.stringify(res), '-------')
      document.querySelector('#display').appendChild(this.program.$mount().$el)
      if (this.css !== '') {
        const styles = document.createElement('style')
        styles.type = 'text/css'
        styles.innerHTML = this.css
        document.getElementsByTagName('head')[0].appendChild(styles)
      }
    },
    reset () {
      document.getElementById('display').innerHTML = ''
      if (this.program) {
        this.program.$destroy()
      }
      this.program = null
    },
    beautifyAction () {
      let a = Beautify.html(this.code)
      this.$emit('Beautify', a)
    }
  }
}
</script>

<style lang="less">
    .mt10 {
        margin-left: 10px;
    }
</style>
